﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using System.Diagnostics;
using System.Runtime.InteropServices;
using ImageMagick;

namespace Image_Conversion
{
    public partial class MainWindow : Form
    {
       
        int QualitySetting;
        List<String> imageExtensions;

        public MainWindow()
        {
            InitializeComponent();
            
            // Create the list of Image Extensions            
            imageExtensions = new List<String>();

            foreach (MagickFormat imgType in Enum.GetValues(typeof(MagickFormat)))
            {
                imageExtensions.Add(imgType.ToString().ToUpper());
            }
            
            // Setup Background Worker Thread            
            backgroundWorker1.WorkerReportsProgress = true;
            backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
            backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);

            
            // Set Defualt Quality         
            QualitySetting = 92;
            QualityBar.Value = QualitySetting;

        }
        
        private delegate ListView.ListViewItemCollection GetItems(ListView lstview);

        private ListView.ListViewItemCollection getListViewItems(ListView lstview)
        {
            ListView.ListViewItemCollection temp = new ListView.ListViewItemCollection(new ListView());
            if (!lstview.InvokeRequired)
            {
                foreach (ListViewItem item in lstview.Items)
                    temp.Add((ListViewItem)item.Clone());
                return temp;
            }
            else
                return (ListView.ListViewItemCollection)this.Invoke(new GetItems(getListViewItems), new object[] { lstview });
        }

        private void QualityBar_ValueChanged(object sender, EventArgs e)
        {
            QualityLabel.Text = QualityBar.Value.ToString();
            QualitySetting = QualityBar.Value;
        }

        private void Lossless_CheckedChanged(object sender, EventArgs e)
        {
            if (Lossless.Checked)
            {                
                QualityBar.Value = 100;
                QualityBar.Enabled = false;
                QualityLabel.Text = "Lossless";
            }
            else
            {
                QualityBar.Enabled = true;
                QualityLabel.Text = QualityBar.Value.ToString();
            }
        }

        private void Convert_Click(object sender, EventArgs e)
        {
            // Incase they get click happy
            if (backgroundWorker1.IsBusy)
                return;
            
            progressBar1.Visible = true;
            progressBar1.Maximum = listView1.Items.Count;

            // Start the background worker           
            backgroundWorker1.RunWorkerAsync();            
        }


        private void listView1_DragDrop(object sender, DragEventArgs e)
        {
            Array FileList = (Array)e.Data.GetData(DataFormats.FileDrop);
            {
                foreach (Object FileName in FileList)
                {
                    FileInfo fInfo = new FileInfo(FileName.ToString());
                    if (IsImage(fInfo.Extension))
                    {
                        ListViewItem file = new ListViewItem(FileName.ToString());
                        listView1.Items.Add(file);
                    }
                }
            }
        }

        private void listView1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
                e.Effect = DragDropEffects.Copy;
            else
                e.Effect = DragDropEffects.None;
        }

        private Boolean IsImage(string Fileextension)
        {
            Fileextension = Fileextension.Substring(1, Fileextension.Length - 1).ToUpper();

            if (Fileextension.Contains(Fileextension))
                return true;

            return false;
        }

        private void JPGButton_CheckedChanged(object sender, EventArgs e)
        {
            Lossless.Enabled = false;
        }

        private void Jpg2000Button_CheckedChanged(object sender, EventArgs e)
        {
            Lossless.Enabled = true;
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i < getListViewItems(listView1).Count; i++)
            {
                // Report progress to the UI
                backgroundWorker1.ReportProgress(i+1);

                // Get the File Name
                string FileName = getListViewItems(listView1)[i].Text;

                // Load the Image
                MagickImage image = new MagickImage(FileName);

                // JPEG Out Put
                if (JPGButton.Checked)
                {
                    image.Quality = QualitySetting;
                    image.Format = MagickFormat.Jpeg;
                    image.CompressionMethod = CompressionMethod.JPEG;

                }

                // JPEG2000
                if (Jpg2000Button.Checked)
                {
                    if (Lossless.Checked)
                    {
                        image.Quality = 100;
                        image.Format = MagickFormat.Jp2;
                        image.CompressionMethod = CompressionMethod.LosslessJPEG;
                    }
                    else
                    {
                        image.Quality = QualitySetting;
                        image.Format = MagickFormat.Jp2;
                        image.CompressionMethod = CompressionMethod.JPEG2000;
                    }
                }

                // New Save Path
                string SaveDir = Path.GetDirectoryName(FileName);
                string SaveFileName = Path.GetFileNameWithoutExtension(FileName) + '.' + image.Format.ToString();
                string Output = Path.Combine(SaveDir, SaveFileName);

                // Save the Image
                try
                {
                    image.Write(Output);
                    
                    // Delete if requested.
                    if (DeleteWhenDone.Checked)
                    {
                        System.IO.File.Delete(FileName); 
                    }

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }       
            }
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {            
            progressBar1.Value = e.ProgressPercentage;
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            progressBar1.Visible = false;
            listView1.Items.Clear();
            MessageBox.Show("Done", "Done", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

    }
}
